/*
 * All header file for c language MUST be include : in extern "C" { }
 */
extern "C" {
#include "../src/uni_string.c"
}

/*
 * H2UNIT is a unit test Suite, which contains several test cases.
 */
H2UNIT(str_test) {
  /*
   * setup() will be executed before every test case belong to this suite.
   * Typically it is used to prepare preconditions.
   */
  void setup() {
  }

  /*
   * teardown() will be executed after every test case belong to this suite.
   * whatever test case passed or failed.
   * Typically it is used to release resource.
   */
  void teardown() {
  }
};


H2CASE(str_test, "StrStrip test") {
  char str_in[100] = {0};
  char *str_null = NULL;
  /* normal cases */
  uni_snprintf(str_in, sizeof(str_in), "%s", "hello");
  StrStrip(str_in);
  H2EQ_STRCMP("hello", str_in);
  uni_snprintf(str_in, sizeof(str_in), "%s", "hello world");
  StrStrip(str_in);
  H2EQ_STRCMP("hello world", str_in);
  uni_snprintf(str_in, sizeof(str_in), "%s", " hello world");
  StrStrip(str_in);
  H2EQ_STRCMP("hello world", str_in);
  uni_snprintf(str_in, sizeof(str_in), "%s", "               hello world");
  StrStrip(str_in);
  H2EQ_STRCMP("hello world", str_in);
  uni_snprintf(str_in, sizeof(str_in), "%s", "				hello world");
  StrStrip(str_in);
  H2EQ_STRCMP("hello world", str_in);
  uni_snprintf(str_in, sizeof(str_in), "%s", "		     \nhello world");
  StrStrip(str_in);
  H2EQ_STRCMP("hello world", str_in);
  uni_snprintf(str_in, sizeof(str_in), "%s", "		     \nhello world\n    ");
  StrStrip(str_in);
  H2EQ_STRCMP("hello world", str_in);
  uni_snprintf(str_in, sizeof(str_in), "%s",
               "		     \nhello world   \n			");
  StrStrip(str_in);
  H2EQ_STRCMP("hello world", str_in);
  uni_snprintf(str_in, sizeof(str_in), "%s",
               "		     \n<hello world >  \n			");
  StrStrip(str_in);
  H2EQ_STRCMP("<hello world >", str_in);
  uni_snprintf(str_in, sizeof(str_in), "%s",
               "		     \n<hello world >]?{}[  \n			");
  StrStrip(str_in);
  H2EQ_STRCMP("<hello world >]?{}[", str_in);
  /* corner cases */
  uni_snprintf(str_in, sizeof(str_in), "%s", "");
  StrStrip(str_in);
  H2EQ_STRCMP("", str_in);
  uni_snprintf(str_in, sizeof(str_in), "%s", " ");
  StrStrip(str_in);
  H2EQ_STRCMP("", str_in);
  uni_snprintf(str_in, sizeof(str_in), "%s", "		\n	  ");
  StrStrip(str_in);
  H2EQ_STRCMP("", str_in);
  StrStrip(str_null);
  H2EQ_TRUE(NULL == str_null);
}

H2CASE(str_test, "StrSub test") {
  char src[100] = {0};
  char dst[100] = {0};
  /* normal case */
  uni_snprintf(src, sizeof(src), "%s", "hello world");
  StrSub(dst, src, "hel", "rld");
  H2EQ_STRCMP("hello world", dst);
  StrSub(dst, src, "el", "rl");
  H2EQ_STRCMP("ello worl", dst);
  StrSub(dst, src, "^", "rl");
  H2EQ_STRCMP("hello worl", dst);
  StrSub(dst, src, "el", "$");
  H2EQ_STRCMP("ello world", dst);
  StrSub(dst, src, "h", "l");
  H2EQ_STRCMP("hel", dst);
  StrSub(dst, "<hello world>", "<", ">");
  H2EQ_STRCMP("<hello world>", dst);
  /* invalid input */
  StrSub(NULL, src, "hel", "rld");
  StrSub(dst, NULL, "hel", "rld");
  H2EQ_TRUE(dst[0] == '\0');
  StrSub(dst, src, NULL, "rld");
  H2EQ_TRUE(dst[0] == '\0');
  StrSub(dst, src, "hel", NULL);
  H2EQ_TRUE(dst[0] == '\0');
  StrSub(dst, src, "", "rld");
  H2EQ_TRUE(dst[0] == '\0');
  StrSub(dst, src, "hel", "");
  H2EQ_TRUE(dst[0] == '\0');
  /* corner case */
  StrSub(dst, src, "hee", "rld");
  H2EQ_TRUE(dst[0] == '\0');
  StrSub(dst, src, "hel", "ldd");
  H2EQ_TRUE(dst[0] == '\0');
  StrSub(dst, src, "hel", "ll");
  H2EQ_STRCMP("hell", dst);
  StrSub(dst, src, "hel", "hel");
  H2EQ_STRCMP("hel", dst);
  StrSub(dst, src, "hel", "he");
  H2EQ_STRCMP("he", dst);
  StrSub(dst, src, "rld", "hel");
  H2EQ_TRUE(dst[0] == '\0');
}

H2CASE(str_test, "StrSubEx test") {
  char src[100] = {0};
  char dst[100] = {0};
  /* normal case */
  uni_snprintf(src, sizeof(src), "%s", "hello world");
  StrSubEx(dst, src, "hel", "rld");
  H2EQ_STRCMP("lo wo", dst);
  StrSubEx(dst, src, "el", "rl");
  H2EQ_STRCMP("lo wo", dst);
  StrSubEx(dst, src, "^", "rl");
  H2EQ_STRCMP("hello wo", dst);
  StrSubEx(dst, src, "el", "$");
  H2EQ_STRCMP("lo world", dst);
  StrSubEx(dst, src, "h", "l");
  H2EQ_STRCMP("e", dst);
  StrSubEx(dst, "<hello world>", "<", ">");
  H2EQ_STRCMP("hello world", dst);
  /* invalid input */
  StrSubEx(NULL, src, "hel", "rld");
  StrSubEx(dst, NULL, "hel", "rld");
  H2EQ_TRUE(dst[0] == '\0');
  StrSubEx(dst, src, NULL, "rld");
  H2EQ_TRUE(dst[0] == '\0');
  StrSubEx(dst, src, "hel", NULL);
  H2EQ_TRUE(dst[0] == '\0');
  StrSubEx(dst, src, "", "rld");
  H2EQ_TRUE(dst[0] == '\0');
  StrSubEx(dst, src, "hel", "");
  H2EQ_TRUE(dst[0] == '\0');
  /* corner case */
  StrSubEx(dst, src, "hee", "rld");
  H2EQ_TRUE(dst[0] == '\0');
  StrSubEx(dst, src, "hel", "ldd");
  H2EQ_TRUE(dst[0] == '\0');
  StrSubEx(dst, src, "hel", "ll");
  H2EQ_TRUE(dst[0] == '\0');
  StrSubEx(dst, src, "hel", "hel");
  H2EQ_TRUE(dst[0] == '\0');
  StrSubEx(dst, src, "hel", "he");
  H2EQ_TRUE(dst[0] == '\0');
  StrSubEx(dst, src, "rld", "hel");
  H2EQ_TRUE(dst[0] == '\0');
}

H2CASE(str_test, "StrLoc test") {
  H2EQ_MATH(0, StrLoc("hello world", "hello"));
  H2EQ_MATH(1, StrLoc("hello world", "ello"));
  H2EQ_MATH(6, StrLoc("hello world", "world"));
  H2EQ_MATH(10, StrLoc("hello world", "d"));
  H2EQ_MATH(-1, StrLoc("hello world", NULL));
  H2EQ_MATH(-1, StrLoc(NULL, "hello"));
  H2EQ_MATH(-1, StrLoc("world", "hello"));
  H2EQ_MATH(-1, StrLoc("hell", "hello"));
}

H2CASE(str_test, "StrReplaceS test") {
  char str[100] = {0};
  uni_snprintf(str, sizeof(str), "12345");
  StrReplaceS(str, "12", "ab");
  H2EQ_STRCMP("ab345", str);
  StrReplaceS(str, "3", "c");
  H2EQ_STRCMP("abc45", str);
  StrReplaceS(str, "45", "de");
  H2EQ_STRCMP("abcde", str);
  StrReplaceS(str, "abcde", "12345");
  H2EQ_STRCMP("12345", str);
  StrReplaceS(str, "134", "abc");
  H2EQ_STRCMP("12345", str);
  StrReplaceS(str, "", "abc");
  H2EQ_STRCMP("12345", str);
  StrReplaceS(str, NULL, "abc");
  H2EQ_STRCMP("12345", str);
  StrReplaceS(NULL, "123", "abc");
  H2EQ_STRCMP("12345", str);
  StrReplaceS(str, "123", "");
  H2EQ_STRCMP("45", str);
  uni_snprintf(str, sizeof(str), "123\n456\tabc def");
  StrReplaceS(str, "\n", " ");
  H2EQ_STRCMP("123 456\tabc def", str);
  StrReplaceS(str, "6\t", " ");
  H2EQ_STRCMP("123 45 abc def", str);
  StrReplaceS(str, " ", "");
  H2EQ_STRCMP("12345abcdef", str);
  uni_snprintf(str, sizeof(str), "\"hello\":\"how are you\"");
  StrReplaceS(str, "\"", "\\\"");
  H2EQ_STRCMP("\\\"hello\\\":\\\"how are you\\\"", str);
}

H2CASE(str_test, "StrReplaceC test") {
  char str[] = "123\n456\tabc def<>(){}123\n456\tabc def<>(){}";
  StrReplaceC(str, '1', 'g');
  H2EQ_STRCMP("g23\n456\tabc def<>(){}g23\n456\tabc def<>(){}", str);
  StrReplaceC(str, 'f', '7');
  H2EQ_STRCMP("g23\n456\tabc de7<>(){}g23\n456\tabc de7<>(){}", str);
  StrReplaceC(str, '\n', ' ');
  H2EQ_STRCMP("g23 456\tabc de7<>(){}g23 456\tabc de7<>(){}", str);
  StrReplaceC(str, '\t', '\n');
  H2EQ_STRCMP("g23 456\nabc de7<>(){}g23 456\nabc de7<>(){}", str);
  StrReplaceC(str, '<', '(');
  H2EQ_STRCMP("g23 456\nabc de7(>(){}g23 456\nabc de7(>(){}", str);
  StrReplaceC(str, '(', ' ');
  H2EQ_STRCMP("g23 456\nabc de7 > ){}g23 456\nabc de7 > ){}", str);
  StrReplaceC(str, '{', ' ');
  H2EQ_STRCMP("g23 456\nabc de7 > ) }g23 456\nabc de7 > ) }", str);
}
